﻿using System;
using System.Drawing;

using Storm.TextEditor.Win32;
using Storm.TextEditor.Win32.Enums;
using Storm.TextEditor.Win32.Structs;

namespace Storm.TextEditor.Core
{
	public class IMEWindow
	{
		#region Fields

		private const int IMC_SETCOMPOSITIONWINDOW = 0x000c;
		private const int CFS_POINT                = 0x0002;
		private const int IMC_SETCOMPOSITIONFONT   = 0x000a;

		private const byte FF_MODERN   = 48;
		private const byte FIXED_PITCH = 1;

		private IntPtr hIMEWnd  = IntPtr.Zero;
		private Font   font     = null;
		private Point  location = new Point(0, 0);

		#endregion

		#region Properties

		public Font Font
		{
			get { return font; }
			set
			{
				if (font.Equals(value) == false)
				{
					SetFont(value);
					font = value;
				}
			}
		}

		public Point Location
		{
			get { return location; }
			set
			{
				location = value;

				POINTAPI p = new POINTAPI();
				p.X = value.X;
				p.Y = value.Y;

				COMPOSITIONFORM lParam = new COMPOSITIONFORM();
				lParam.dwStyle = CFS_POINT;
				lParam.ptCurrentPos = p;
				lParam.rcArea = new RECTAPI();

				NativeUser32Api.SendMessage(
					hIMEWnd,
					(int)WindowMessage.WM_IME_CONTROL,
					IMC_SETCOMPOSITIONWINDOW,
					lParam);
			}
		}

		#endregion

		#region Methods

		#region Public

		public void SetFont(Font font)
		{
			LogFont lf = new LogFont();
			font.ToLogFont(lf);
			lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;

			NativeUser32Api.SendMessage(
				hIMEWnd, (int)WindowMessage.WM_IME_CONTROL,
				IMC_SETCOMPOSITIONFONT,
				lf);
		}

		public void SetFont(string fontname, float fontsize)
		{
			LogFont tFont = new LogFont();
			tFont.lfItalic = (byte)0;
			tFont.lfStrikeOut = (byte)0;
			tFont.lfUnderline = (byte)0;
			tFont.lfWeight = 400;
			tFont.lfWidth = 0;
			tFont.lfHeight = (int)(-fontsize * 1.3333333333333);
			tFont.lfCharSet = 1;
			tFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
			tFont.lfFaceName = fontname;

			LogFont lf = tFont;

			NativeUser32Api.SendMessage(
				hIMEWnd, (int)WindowMessage.WM_IME_CONTROL,
				IMC_SETCOMPOSITIONFONT,
				lf);
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of IMEWindow.
		/// </summary>
		public IMEWindow(IntPtr hWnd, string fontname, float fontsize)
		{
			hIMEWnd = NativeImm32Api.ImmGetDefaultIMEWnd(hWnd);
			SetFont(fontname, fontsize);
		}
	}
}
